Skip to content

[Feature] sse 연결 시점을 앱 시작 시점으로 변경 및 react-native-svg 라이브러리 업그레이드#90

Merged
dioo1461 merged 6 commits intodevfrom
feature/sse-connection
Feb 6, 2026
Merged

[Feature] sse 연결 시점을 앱 시작 시점으로 변경 및 react-native-svg 라이브러리 업그레이드#90
dioo1461 merged 6 commits intodevfrom
feature/sse-connection

Conversation

@dioo1461
Copy link
Collaborator

@dioo1461 dioo1461 commented Feb 6, 2026

  • close #

✨ 구현 기능 명세

  • sse 연결 시점을 앱 시작 시점으로 변경하여, 앱 사용 중 커넥션 연결/해제 횟수를 줄였습니다.
  • Windows 환경에서의 버벅임 문제를 해결하기 위해 react-native-svg 라이브러리를 업그레이드하였습니다.

✅ PR Point

😭 어려웠던 점

@dioo1461 dioo1461 requested a review from Copilot February 6, 2026 11:10
@dioo1461 dioo1461 self-assigned this Feb 6, 2026
@dioo1461 dioo1461 added the ✨ feature 새로운 기능 구현 label Feb 6, 2026
@gemini-code-assist
Copy link

Summary of Changes

Hello @dioo1461, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 PR은 앱의 전반적인 성능과 사용자 경험을 개선하기 위한 중요한 변경 사항들을 포함합니다. SSE 연결 방식을 최적화하여 리소스 사용을 줄이고, 특정 플랫폼에서의 라이브러리 성능 문제를 해결합니다. 또한, 그룹 관리 로직을 개선하고 채팅 메시지 알림 시스템을 더욱 견고하게 만듭니다.

Highlights

  • SSE 연결 시점 변경: SSE(Server-Sent Events) 연결 시점을 앱 시작 시점으로 변경하여, 앱 사용 중 발생하는 연결/해제 횟수를 줄였습니다. 이는 SSEProvider 컴포넌트를 통해 전역적으로 관리됩니다.
  • react-native-svg 라이브러리 업그레이드: Windows 환경에서의 성능 저하 문제를 해결하기 위해 react-native-svg 라이브러리를 버전 15.11.2에서 15.15.2로 업그레이드했습니다.
  • 그룹 공개 여부 로직 변경 및 UI 업데이트: 그룹의 공개 여부를 isOpen 속성 대신 isApprovalRequired 속성을 기반으로 판단하도록 로직을 변경하고, 관련 UI 텍스트 및 기본값을 업데이트했습니다.
  • 채팅방 읽지 않은 메시지 수 관리 개선: 새로운 SSEProvideruseChatCount 훅을 도입하여 채팅방별 읽지 않은 메시지 수를 중앙에서 효율적으로 관리하고 실시간으로 업데이트할 수 있도록 했습니다.
Changelog
  • package-lock.json
    • react-native-svg 의존성 버전이 15.11.2에서 15.15.2로 업데이트되었습니다.
  • package.json
    • react-native-svg 의존성 버전이 15.11.2에서 15.15.2로 업데이트되었습니다.
  • src/App.tsx
    • SSEProvider가 새로 임포트되었고, SplashRenderer 컴포넌트를 감싸도록 추가되어 앱 시작 시 SSE 연결이 이루어지도록 변경되었습니다.
  • src/SSEProvider.tsx
    • 새로운 파일로, 채팅방의 읽지 않은 메시지 수를 관리하는 전역 SSE 스토어를 제공합니다. 앱 마운트 시 SSE에 연결하고 언마운트 시 연결을 해제합니다.
  • src/features/chat/sse/useChatCount.ts
    • 새로운 파일로, useSyncExternalStoreSSEProvider를 활용하여 특정 채팅방의 읽지 않은 메시지 수를 실시간으로 제공하는 훅이 추가되었습니다.
  • src/hooks/useChatRoomListSse/index.ts
    • SSE 연결 지연 및 UX 개선에 대한 TODO 주석이 제거되었습니다. 이는 SSEProvider 도입으로 해결된 것으로 보입니다.
  • src/locales/ko/createGroup.json
    • 그룹 생성 관련 번역 키 publicity-labelmake-publicity-private으로 변경되었고, 해당 텍스트 내용도 업데이트되었습니다.
  • src/screens/bottomTab/GroupsScreen/components/JoinedGroupPanel/index.tsx
    • 그룹 목록 아이템에서 isPublic 속성이 group.isOpen 대신 !group.isApprovalRequired를 사용하도록 변경되었습니다.
  • src/screens/group/CreateGroupScreen/components/GroupPublicityInput.tsx
    • 그룹 공개 여부 입력 컴포넌트에서 사용되는 번역 키가 publicity-label에서 make-publicity-private으로 변경되었고, 힌트 메시지 로직도 isPublic의 반대 값으로 변경되었습니다.
  • src/screens/group/CreateGroupScreen/index.tsx
    • 그룹 생성 화면에서 GroupPublicityInputisApprovalRequired 기본값이 true에서 false로 변경되었습니다.
  • src/screens/group/groupDetail/GroupDetailScreen/index.tsx
    • 기존에 useFocusEffect를 사용하여 로컬에서 관리되던 SSE 연결 및 채팅 카운트 로직이 제거되었고, 새로 추가된 useChatCount 훅을 통해 전역 SSEProvider에서 채팅 카운트를 가져오도록 변경되었습니다.
Activity
  • PR 작성자 dioo1461이(가) 이 변경 사항을 제출했습니다.
  • Server-Sent Events(SSE) 연결 방식이 앱 시작 시점으로 변경되어, 앱의 생명주기에 맞춰 연결이 관리됩니다.
  • react-native-svg 라이브러리가 업데이트되어 Windows 환경에서의 성능 문제가 개선되었습니다.
  • 새로운 파일 src/SSEProvider.tsxsrc/features/chat/sse/useChatCount.ts가 추가되어 SSE 기반의 채팅 알림 관리가 중앙 집중화되었습니다.
  • 기존 파일들은 새로운 SSE 프로바이더와 통합되고, 그룹 공개 여부 로직 변경에 따라 수정되었습니다.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

이 PR은 두 가지 주요 변경 사항을 포함합니다: SSE 연결 관리 방식을 앱 전역 Provider로 중앙화하여 개선하고, 그룹 생성 시 공개/비공개 설정 로직을 변경했습니다. 또한 react-native-svg 라이브러리를 업그레이드했습니다.

전반적으로 코드 변경은 긍정적이며, 특히 SSE 연결 로직을 SSEProvider로 분리하여 재사용성을 높이고 관련 컴포넌트의 코드를 크게 단순화한 점이 좋습니다.

한 가지 개선점을 제안했습니다. SSEProvider 내에 중복된 useEffect 로직이 있어 이를 제거하여 코드를 더 명확하고 간결하게 만들 수 있습니다. 자세한 내용은 개별 코멘트를 참고해주세요.

Comment on lines 41 to 56
const { connect, disconnect } = useChatRoomListSse({
onInitMessage: (payload) => {
payload.rooms?.forEach(r => {
const count = Math.max(0, r.unread ?? 0);
store.setCount(r.roomId, count);
});
},
onNewMessage: (payload) => {
store.inc(payload.roomId);
},
});

useEffect(() => {
connect();
return () => disconnect();
}, [connect, disconnect]);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

useChatRoomListSse 훅은 내부적으로 useEffect를 사용하여 accessToken의 변경에 따라 자동으로 SSE 연결 및 해제를 관리합니다. 따라서 SSEProvider 컴포넌트에서 useEffect를 사용하여 수동으로 connectdisconnect를 호출하는 것은 중복된 로직입니다. 이로 인해 코드가 복잡해지고 잠재적인 혼란을 야기할 수 있습니다.

useChatRoomListSse 훅이 연결 생명주기를 자체적으로 처리하도록 하고, SSEProvider에서는 불필요한 useEffectconnect, disconnect 변수 선언을 제거하는 것이 좋습니다.

Suggested change
const { connect, disconnect } = useChatRoomListSse({
onInitMessage: (payload) => {
payload.rooms?.forEach(r => {
const count = Math.max(0, r.unread ?? 0);
store.setCount(r.roomId, count);
});
},
onNewMessage: (payload) => {
store.inc(payload.roomId);
},
});
useEffect(() => {
connect();
return () => disconnect();
}, [connect, disconnect]);
useChatRoomListSse({
onInitMessage: (payload) => {
payload.rooms?.forEach(r => {
const count = Math.max(0, r.unread ?? 0);
store.setCount(r.roomId, count);
});
},
onNewMessage: (payload) => {
store.inc(payload.roomId);
},
});

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a2d293ab21

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines 56 to 59
groupId={group.groupId}
groupName={group.groupName}
isPublic={group.isOpen}
isPublic={!group.isApprovalRequired}
participantImageUrls={[leaderImageUrl, ...otherImageUrls]}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Use isOpen instead of inverting isApprovalRequired

GetGroupsResponse exposes both isOpen and isApprovalRequired as independent fields (see src/features/groups/model/groups.ts), so treating isPublic as !isApprovalRequired can be wrong when a group is publicly searchable but still requires approval. This also makes the list view disagree with the detail view, which still uses params.isOpen. In those cases, groups will be labeled private in the list even though they are open. Prefer using group.isOpen (or whatever the API contract defines) for public/private status.

Useful? React with 👍 / 👎.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR refactors the SSE (Server-Sent Events) connection architecture to establish a single persistent connection at app startup, upgrades the react-native-svg library to address Windows performance issues, and adjusts the group creation default settings for publicity.

Changes:

  • Centralized SSE connection management by introducing an SSEProvider that connects once at app startup and maintains a global store for chat room unread counts
  • Upgraded react-native-svg from 15.11.2 to 15.15.2 to fix Windows performance issues
  • Changed the default group publicity setting from private (approval required) to public (no approval required)

Reviewed changes

Copilot reviewed 10 out of 11 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
src/SSEProvider.tsx New provider component that manages a single SSE connection and exposes a global store for chat room unread counts using useSyncExternalStore pattern
src/features/chat/sse/useChatCount.ts New hook that subscribes to the global SSE store to get unread count for a specific chat room
src/App.tsx Wraps the app with SSEProvider to establish SSE connection at startup
src/screens/group/groupDetail/GroupDetailScreen/index.tsx Simplified by removing local SSE connection management and using the new useChatCount hook
src/screens/group/CreateGroupScreen/index.tsx Changed default value for isApprovalRequired from true to false, making groups public by default
src/screens/group/CreateGroupScreen/components/GroupPublicityInput.tsx Updated label and hint logic to reflect the new semantics where the checkbox means "make private" rather than "make public"
src/screens/bottomTab/GroupsScreen/components/JoinedGroupPanel/index.tsx Changed logic to determine if group is public from group.isOpen to !group.isApprovalRequired
src/locales/ko/createGroup.json Updated label from "그룹 공개하기" (make group public) to "비공개 그룹으로 만들기" (make group private)
src/hooks/useChatRoomListSse/index.ts Removed TODO comment about UX improvements, as it's being addressed by this PR
package.json, package-lock.json Upgraded react-native-svg from 15.11.2 to 15.15.2
Comments suppressed due to low confidence (1)

src/screens/group/CreateGroupScreen/index.tsx:49

  • The form is missing the isOpen field, but the CreateGroupRequest type requires it. The form only provides values for name, tag, maxMember, and isApprovalRequired. This will cause the submitted data to be incomplete and may result in API validation errors. You should either add a Form element for the isOpen field or set a default value using the useFormProps prop on the Form component.
          <Form gap={20}>
            <GroupNameInput defaultValue='' formName='name' />
            <GroupTagInput defaultValue='' formName='tag' />
            <GroupMaxMemberInput defaultValue={20} formName='maxMember' />
            <GroupPublicityInput defaultValue={false} formName='isApprovalRequired' />
            <Form.SubmitButton onSubmit={onSubmit}>
              {(submit, disabled) => (
                <Button.Basic disabled={disabled} onPress={submit}>
                  {tCreateGroup}
                </Button.Basic>
              )}
            </Form.SubmitButton>
          </Form>

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 31 to 32
hint={!isPublic ? tPublicityDescriptionPublic : tPublicityDescriptionPrivate}
label={tMakePublicityPrivate}
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hint logic appears to be inverted. The variable isPublic is watching isApprovalRequired (which represents whether the group is private). When the checkbox is unchecked (isApprovalRequired=false, group is public), isPublic is false, so !isPublic is true and it shows the public description, which is correct. However, the variable name isPublic is very misleading here since it actually holds the value of isApprovalRequired. This makes the code harder to understand and maintain.

Copilot uses AI. Check for mistakes.
return <SseContext.Provider value={store}>{children}</SseContext.Provider>;
};

export const useSSEContext = () =>useSafeContext(SseContext);
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing space between function name and parentheses. Should be useSSEContext = () => useSafeContext with a space after the arrow.

Suggested change
export const useSSEContext = () =>useSafeContext(SseContext);
export const useSSEContext = () => useSafeContext(SseContext);

Copilot uses AI. Check for mistakes.
@dioo1461 dioo1461 merged commit 4f34f73 into dev Feb 6, 2026
1 check passed
@dioo1461 dioo1461 deleted the feature/sse-connection branch February 6, 2026 11:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ feature 새로운 기능 구현

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants